package org.urbansoft.icl.record;

import java.util.ArrayList;

import org.apache.log4j.Logger;

import org.urbansoft.icl.field.Field;
import org.urbansoft.icl.field.GenericAField;
import org.urbansoft.icl.field.GenericANField;
import org.urbansoft.icl.field.GenericANSField;
import org.urbansoft.icl.field.GenericBlankField;
import org.urbansoft.icl.field.GenericNField;
import org.urbansoft.icl.field.Position;
import org.urbansoft.icl.field.Usage;
import org.urbansoft.icl.field.ValidationCriteria;
import org.urbansoft.icl.field.validation.FileIDModifierValidator;
import org.urbansoft.icl.field.validation.RecordTypeValidator;
import org.urbansoft.icl.field.validation.ResendIndicatorValidator;
import org.urbansoft.icl.field.validation.RoutingNumberValidator;
import org.urbansoft.icl.field.validation.StandardLevelValidator;
import org.urbansoft.icl.field.validation.TestFileIndicatorValidator;
import org.urbansoft.icl.util.EasternStandardTime;

/**
 * The Class FileHeaderRecord.
 */
public class FileHeaderRecord extends Record {
	public Field recordType;
	public Field standardLevel;
	public Field testFileIndicator;
	public Field immediateDestinationRoutingNumber;
	public Field immediateOriginRoutingNumber;
	public Field fileCreationDate;
	public Field fileCreationTime;
	public Field resendIndicator;
	public Field immediateDesitinationName;
	public Field immediateOriginName;
	public Field fileIDModifier;
	public Field countryCode;
	public Field userField;
	public Field companion;
	public Field reserved;

	private static Logger log = Logger.getLogger(FileHeaderRecord.class);

	/**
	 * Instantiates a new file header record.
	 */
	public FileHeaderRecord() {
		fields = new ArrayList<Field>();
		recordName = "File Header Record";
		recordTypeNumber = "01";
		initFields();
	}

	/**
	 * Constructor para lectura
	 * 
	 * @param read
	 */
	public FileHeaderRecord(String read) {
		// log.info("New FileHeaderRecord for READ");
		fields = new ArrayList<Field>();
		recordName = "File Header Record";
		recordTypeNumber = "01";
		initFields2();
	}

	/**
	 * Cosntructor para creación desde X9 desde un INP
	 * 
	 * @param read
	 */
	public FileHeaderRecord(int write) {
		// log.info("New FileHeaderRecord for READ");
		fields = new ArrayList<Field>();
		recordName = "File Header Record";
		recordTypeNumber = "01";
		initFields3();
	}

	/**
	 * Inicio por defecto para X9 USA, tiene hasta 80 caracteres
	 */
	private void initFields() {
		try {
			/* header record */
			recordType = new GenericNField(new Position(1, 2),
					RecordTypeValidator.INSTANCE, "01", "Record Type");

			/* default to DSTU X9.37-2003 */
			standardLevel = new GenericNField(new Position(3, 4),
					StandardLevelValidator.INSTANCE, "03", "Standard Level");
			standardLevel.setValidationCriteria(ValidationCriteria.REQUIRED);

			/* default to a test file */
			testFileIndicator = new GenericAField(new Position(5, 5),
					TestFileIndicatorValidator.INSTANCE, "P",
					"Test File Indicator");

			/* create the two routing number fields */
			immediateDestinationRoutingNumber = new GenericNField(new Position(
					6, 14), "Immediate Destination Routing Number");
			immediateDestinationRoutingNumber
					.setFieldValidator(RoutingNumberValidator.INSTANCE);
			immediateDestinationRoutingNumber
					.setValidationCriteria(ValidationCriteria.REQUIRED_IF_PRESENT);

			immediateOriginRoutingNumber = new GenericNField(new Position(15,
					23), "Immediate Origin Routing Number");
			immediateOriginRoutingNumber
					.setFieldValidator(RoutingNumberValidator.INSTANCE);
			immediateOriginRoutingNumber
					.setValidationCriteria(ValidationCriteria.REQUIRED);

			/* default date and time to now */
			fileCreationDate = new GenericNField(new Position(24, 31), null,
					EasternStandardTime.getCurrentDateInEST(),
					"File Creation Date");
			fileCreationTime = new GenericNField(new Position(32, 35), null,
					EasternStandardTime.getCurrentTimeInEST(),
					"File Creation Time");

			/* resend indicator is 'N' always */
			resendIndicator = new GenericAField(new Position(36, 36),
					ResendIndicatorValidator.INSTANCE, "N", "Resend Indicator");

			/* destination name has different validation and usage per ucd v1 */
			immediateDesitinationName = new GenericANField(
					new Position(37, 54), "Immediate Destination Name");
			immediateDesitinationName.setUsage(Usage.CONDITIONAL);

			/* origin name has different validation and usage per ucd v1 */
			immediateOriginName = new GenericANField(new Position(55, 72),
					"Immediate Origin Name");
			immediateOriginName.setUsage(Usage.CONDITIONAL);

			/* file id modifier */
			fileIDModifier = new GenericANField(new Position(73, 73),
					"File ID Modifier");
			fileIDModifier.setFieldValidator(FileIDModifierValidator.INSTANCE);
			fileIDModifier
					.setValidationCriteria(ValidationCriteria.REQUIRED_IF_PRESENT);

			/* country code has no validator */
			countryCode = new GenericAField(new Position(74, 75),
					"Country Code");
			countryCode.setUsage(Usage.CONDITIONAL);
			countryCode.setFieldData("");

			/* user field has no validator */
			userField = new GenericANSField(new Position(76, 79), "User Field");
			userField.setUsage(Usage.CONDITIONAL);
			userField.setFieldData("");

			/* reserved - often the companion document */
			reserved = new GenericBlankField(new Position(80, 80), "Reserved");
			reserved.setFieldData("");

			fields.add(recordType);
			fields.add(standardLevel);
			fields.add(testFileIndicator);
			fields.add(immediateDestinationRoutingNumber);
			fields.add(immediateOriginRoutingNumber);
			fields.add(fileCreationDate);
			fields.add(fileCreationTime);
			fields.add(resendIndicator);
			fields.add(immediateDesitinationName);
			fields.add(immediateOriginName);
			fields.add(fileIDModifier);
			fields.add(countryCode);
			fields.add(userField);
			fields.add(reserved);
		} catch (Exception e) {
			log.fatal(e.getMessage(), e);
		}
	}

	/**
	 * Constructor para lectura y edición de un X9 ya existente
	 */
	private void initFields2() {
		try {
			/* header record */
			recordType = new GenericANField(new Position(1, 2), "Record Type");

			/* default to DSTU X9.37-2003 */
			standardLevel = new GenericANField(new Position(3, 4),
					"Standard Level");
			standardLevel.setValidationCriteria(ValidationCriteria.REQUIRED);

			/* default to a test file */
			testFileIndicator = new GenericANField(new Position(5, 5),
					"Test File Indicator");

			/* create the two routing number fields */
			immediateDestinationRoutingNumber = new GenericANField(
					new Position(6, 14), "Immediate Destination Routing Number");
			// immediateDestinationRoutingNumber.setFieldValidator(RoutingNumberValidator.INSTANCE);
			// immediateDestinationRoutingNumber.setValidationCriteria(ValidationCriteria.REQUIRED_IF_PRESENT);

			immediateOriginRoutingNumber = new GenericANField(new Position(15,
					23), "Immediate Origin Routing Number");
			// immediateOriginRoutingNumber.setFieldValidator(RoutingNumberValidator.INSTANCE);
			// immediateOriginRoutingNumber.setValidationCriteria(ValidationCriteria.REQUIRED);

			/* default date and time to now */
			fileCreationDate = new GenericANField(new Position(24, 31),
					"File Creation Date");
			fileCreationTime = new GenericANField(new Position(32, 35),
					"File Creation Time");

			/* resend indicator is 'N' always */
			resendIndicator = new GenericANField(new Position(36, 36),
					"Resend Indicator");

			/* destination name has different validation and usage per ucd v1 */
			immediateDesitinationName = new GenericANSField(
					new Position(37, 54), "Immediate Destination Name");
			immediateDesitinationName.setUsage(Usage.CONDITIONAL);

			/* origin name has different validation and usage per ucd v1 */
			immediateOriginName = new GenericANField(new Position(55, 72),
					"Immediate Origin Name");
			immediateOriginName.setUsage(Usage.CONDITIONAL);

			/* file id modifier */
			fileIDModifier = new GenericANField(new Position(73, 73),
					"File ID Modifier");
			fileIDModifier.setFieldValidator(FileIDModifierValidator.INSTANCE);
			fileIDModifier
					.setValidationCriteria(ValidationCriteria.REQUIRED_IF_PRESENT);

			/* country code has no validator */
			countryCode = new GenericANField(new Position(74, 75),
					"Country Code");
			countryCode.setUsage(Usage.CONDITIONAL);

			/* user field has no validator */
			userField = new GenericANField(new Position(76, 79), "User Field");
			userField.setUsage(Usage.CONDITIONAL);

			/* reserved - often the companion document */
			companion = new GenericANField(new Position(80, 80),
					"Companion Document Indicator");

			/* reserved - often the companion document */
			reserved = new GenericANField(new Position(81, 90), "Reserved");

			fields.add(recordType);
			fields.add(standardLevel);
			fields.add(testFileIndicator);
			fields.add(immediateDestinationRoutingNumber);
			fields.add(immediateOriginRoutingNumber);
			fields.add(fileCreationDate);
			fields.add(fileCreationTime);
			fields.add(resendIndicator);
			fields.add(immediateDesitinationName);
			fields.add(immediateOriginName);
			fields.add(fileIDModifier);
			fields.add(countryCode);
			fields.add(userField);
			fields.add(companion);
			fields.add(reserved);
		} catch (Exception e) {
			log.fatal(e.getMessage(), e);
		}
	}

	/**
	 * Constructor para creación a partir de un INP Es el 3 porque este
	 * registro no se usa en la inserción, se ahora un constructor
	 */
	private void initFields3() {
		try {
			/* header record */
			recordType = new GenericANField(new Position(1, 2),
					RecordTypeValidator.INSTANCE, "01", "Record Type");

			/* default to DSTU X9.37-2003 */
			standardLevel = new GenericANField(new Position(3, 4),
					"Standard Level");
			standardLevel.setValidationCriteria(ValidationCriteria.REQUIRED);
			standardLevel.setFieldData("03");

			/* default to a test file */
			testFileIndicator = new GenericANField(new Position(5, 5),
					"Test File Indicator");
			testFileIndicator.setFieldData("P");

			/* create the two routing number fields */
			immediateDestinationRoutingNumber = new GenericANField(
					new Position(6, 14), "Immediate Destination Routing Number");

			immediateOriginRoutingNumber = new GenericANField(new Position(15,
					23), "Immediate Origin Routing Number");

			/* default date and time to now */
			fileCreationDate = new GenericANField(new Position(24, 31),
					"File Creation Date");
			fileCreationDate.setFieldData(EasternStandardTime
					.getCurrentDateInEST());

			fileCreationTime = new GenericANField(new Position(32, 35),
					"File Creation Time");
			fileCreationTime.setFieldData(EasternStandardTime
					.getCurrentTimeInEST());

			/* resend indicator is 'N' always */
			resendIndicator = new GenericANField(new Position(36, 36),
					"Resend Indicator");
			resendIndicator.setFieldData("N");

			/* destination name has different validation and usage per ucd v1 */
			immediateDesitinationName = new GenericANField(
					new Position(37, 54), "Immediate Destination Name");
			immediateDesitinationName.setUsage(Usage.CONDITIONAL);
			immediateDesitinationName.setFieldData("SINACOFI");

			/* origin name has different validation and usage per ucd v1 */
			immediateOriginName = new GenericANField(new Position(55, 72),
					"Immediate Origin Name");
			immediateOriginName.setUsage(Usage.CONDITIONAL);
			immediateOriginName.setFieldData("");

			/* file id modifier */
			fileIDModifier = new GenericANField(new Position(73, 73),
					"File ID Modifier");
			fileIDModifier.setFieldValidator(FileIDModifierValidator.INSTANCE);
			fileIDModifier
					.setValidationCriteria(ValidationCriteria.REQUIRED_IF_PRESENT);
			fileIDModifier.setFieldData("");

			/* country code has no validator */
			countryCode = new GenericANField(new Position(74, 75),
					"Country Code");
			countryCode.setUsage(Usage.CONDITIONAL);
			countryCode.setFieldData("CL");

			/* user field has no validator */
			userField = new GenericANField(new Position(76, 79), "User Field");
			userField.setUsage(Usage.CONDITIONAL);
			userField.setFieldData("");

			/* reserved - often the companion document */
			companion = new GenericANField(new Position(80, 80),
					"Companion Document Indicator");
			companion.setFieldData("");

			/* reserved - often the companion document */
			reserved = new GenericANField(new Position(81, 90), "Reserved");
			reserved.setFieldData("");

			fields.add(recordType);
			fields.add(standardLevel);
			fields.add(testFileIndicator);
			fields.add(immediateDestinationRoutingNumber);
			fields.add(immediateOriginRoutingNumber);
			fields.add(fileCreationDate);
			fields.add(fileCreationTime);
			fields.add(resendIndicator);
			fields.add(immediateDesitinationName);
			fields.add(immediateOriginName);
			fields.add(fileIDModifier);
			fields.add(countryCode);
			fields.add(userField);
			fields.add(companion);
			fields.add(reserved);
		} catch (Exception e) {
			log.fatal(e.getMessage(), e);
		}
	}

}
